package com.zhiche.lisa.bms.service.psup.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zhiche.lisa.bms.dao.mapper.psup.PsupFixedPriceMapper;
import com.zhiche.lisa.bms.dao.model.psup.PsupFixedPrice;
import com.zhiche.lisa.bms.enums.SdCommonEnum;
import com.zhiche.lisa.bms.pojo.dto.util.LspFleetDTO;
import com.zhiche.lisa.bms.pojo.vo.psup.PsupFixedPriceVO;
import com.zhiche.lisa.bms.service.psup.PsupFixedPriceService;
import com.zhiche.lisa.bms.service.utils.LspUtil;
import com.zhiche.lisa.bms.utils.ToolCommonUtils;
import com.zhiche.lisa.core.supports.BaseException;
import com.zhiche.lisa.core.utils.Account.AccountUtil;
import com.zhiche.lisa.core.utils.Account.JwtAccountVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 人送供方一口价 服务实现类
 * </p>
 *
 * @author linbao
 * @since 2019-06-18
 */
@Service
@Slf4j
public class PsupFixedPriceServiceImpl extends ServiceImpl<PsupFixedPriceMapper, PsupFixedPrice> implements PsupFixedPriceService {

    @Autowired
    private LspUtil lspUtil;

    /**
     * 分页查询
     *
     * @param page
     * @return
     */
    @Override
    public Page<PsupFixedPriceVO> queryFixedPricePage(Page<PsupFixedPrice> page) {
        log.info("PsupFixedPriceServiceImpl.queryFixedPricePage param: {}", page);
        EntityWrapper<PsupFixedPrice> ew = buildCondition(page.getCondition());
        List<PsupFixedPrice> psupFixedPriceList = baseMapper.selectPage(page, ew);

        Page<PsupFixedPriceVO> voPage = new Page<>();
        BeanUtils.copyProperties(page, voPage);
        if (CollectionUtils.isNotEmpty(psupFixedPriceList)) {
            List<PsupFixedPriceVO> voList = Lists.newArrayList();
            psupFixedPriceList.forEach(fixedPrice -> {
                PsupFixedPriceVO vo = new PsupFixedPriceVO();
                BeanUtils.copyProperties(fixedPrice, vo);
                voList.add(vo);
            });
            voPage.setRecords(voList);
        }
        return voPage;
    }

    /**
     * 条件查询
     *
     * @param condition
     * @return
     */
    @Override
    public List<PsupFixedPriceVO> queryFixedPriceListByCondition(Map<String, Object> condition) {
        log.info("PsupFixedPriceServiceImpl.queryFixedPriceListByCondition param: {}", condition);
        EntityWrapper<PsupFixedPrice> ew = buildCondition(condition);
        List<PsupFixedPrice> psupFixedPriceList = baseMapper.selectList(ew);

        if (CollectionUtils.isNotEmpty(psupFixedPriceList)) {
            List<PsupFixedPriceVO> voList = Lists.newArrayList();
            psupFixedPriceList.forEach(fixedPrice -> {
                PsupFixedPriceVO vo = new PsupFixedPriceVO();
                BeanUtils.copyProperties(fixedPrice, vo);
                // 状态
                if (Objects.nonNull(fixedPrice.getStatus())) {
                    vo.setStatusStr(SdCommonEnum.getStatusValue(fixedPrice.getStatus()));
                }
                // 生效时间
                if (Objects.nonNull(fixedPrice.getEffectiveDate())) {
                    vo.setEffectiveDateStr(new DateTime(fixedPrice.getEffectiveDate()).toString(ToolCommonUtils.yyyyMMdd));
                }
                // 失效时间
                if (Objects.nonNull(fixedPrice.getInvalidDate())) {
                    vo.setInvalidDateStr(new DateTime(fixedPrice.getInvalidDate()).toString(ToolCommonUtils.yyyyMMdd));
                }
                voList.add(vo);
            });
            return voList;
        }
        return null;
    }

    /**
     * 这对excel的批量导入
     *
     * @param fixedPriceVOList
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public List<String> createBatchFixedPriceForExcel(List<PsupFixedPriceVO> fixedPriceVOList, String token) {
        if (CollectionUtils.isNotEmpty(fixedPriceVOList)) {
            // 校验
            List<String> resultMsgList = verifyInsertParam(fixedPriceVOList, token);
            if (CollectionUtils.isNotEmpty(resultMsgList)) {
                return resultMsgList;
            }
            List<PsupFixedPrice> insertFixedPriceList = Lists.newArrayList();
            JwtAccountVO account = AccountUtil.getAccountInfoFromSecurityContext();
            fixedPriceVOList.forEach(fixedPriceVO -> {
                PsupFixedPrice psupFixedPrice = new PsupFixedPrice();
                BeanUtils.copyProperties(fixedPriceVO, psupFixedPrice);
                psupFixedPrice.setGmtCreate(new Date());
                // 2019-10-30 创建人/上传人
                psupFixedPrice.setCreatorName(account.getUsername());
                insertFixedPriceList.add(psupFixedPrice);
            });
            if (CollectionUtils.isNotEmpty(insertFixedPriceList)) {
                this.insertBatch(insertFixedPriceList);
            }
        }
        return null;
    }

    /**
     * 批量审核
     *
     * @param idList
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public List<String> auditBatchFixedPrice(List<Long> idList) {
        if (CollectionUtils.isEmpty(idList)) {
            throw new BaseException("请选择数据!");
        }
        List<String> resultMsgList = Lists.newArrayList();
        EntityWrapper<PsupFixedPrice> ew = new EntityWrapper<>();
        ew.in("id", idList);
        ew.ne("status", SdCommonEnum.NEW.getCode());
        int count = this.selectCount(ew);

        List<PsupFixedPrice> udpateFixedPriceList = Lists.newArrayList();
        JwtAccountVO account = AccountUtil.getAccountInfoFromSecurityContext();
        if (count > 0) {
            throw new BaseException("存在非新增状态的数据, 不可审核!");
        } else {
            // 校验是否冲突
            List<PsupFixedPrice> psupFixedPriceList = this.selectBatchIds(idList);
            if (CollectionUtils.isNotEmpty(psupFixedPriceList)) {
                psupFixedPriceList.forEach(fixedPrice -> {
                    Integer countByFleet = getCountByFleet(fixedPrice);
                    if (countByFleet > 0) {
                        StringBuilder sb = new StringBuilder();
                        sb.append("数据:").append("车队-").append(fixedPrice.getFleetName()).append(":线路有效期冲突");
                        resultMsgList.add(sb.toString());
                    } else {
                        // 2019-10-30 审核人
                        fixedPrice.setActivitiName(account.getUsername());
                        fixedPrice.setStatus(SdCommonEnum.AUDIT.getCode());
                        udpateFixedPriceList.add(fixedPrice);
                    }
                });
            }
        }
        if (CollectionUtils.isNotEmpty(resultMsgList)) {
            return resultMsgList;
        }
        if (CollectionUtils.isNotEmpty(udpateFixedPriceList)) {
            this.updateBatchById(udpateFixedPriceList);
        }
        return null;
    }

    /**
     * 获取是否存在的数量
     *
     * @param psupFixedPrice
     * @return
     */
    private Integer getCountByFleet(PsupFixedPrice psupFixedPrice) {
        Map<String, Object> condition = Maps.newHashMap();
        if (Objects.nonNull(psupFixedPrice.getEffectiveDate())) {
            condition.put("effectiveDate", new DateTime(psupFixedPrice.getEffectiveDate()).toString(ToolCommonUtils.yyyyMMdd));
        }
        if (Objects.nonNull((psupFixedPrice.getInvalidDate()))) {
            condition.put("invalidDate", new DateTime(psupFixedPrice.getInvalidDate()).toString(ToolCommonUtils.yyyyMMdd));
        }
        condition.put("fleetId", psupFixedPrice.getFleetId());
        condition.put("contractVehicle", psupFixedPrice.getContractVehicle());
        condition.put("notEqId", psupFixedPrice.getId());
        // 起运/目的 省市区
        condition.put("startProvince", psupFixedPrice.getStartProvince());
        condition.put("startCity", psupFixedPrice.getStartCity());
        condition.put("startCounty", psupFixedPrice.getStartCounty());
        condition.put("startName", psupFixedPrice.getStartName());
        condition.put("endProvince", psupFixedPrice.getEndProvince());
        condition.put("endCity", psupFixedPrice.getEndCity());
        condition.put("endCounty", psupFixedPrice.getEndCounty());
        condition.put("endName", psupFixedPrice.getEndName());
        return baseMapper.verifyIsExistDate(condition);
    }

    /**
     * 批量删除
     *
     * @param idList
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public List<String> deleteBatchFixedPrice(List<Long> idList) {
        if (CollectionUtils.isEmpty(idList)) {
            throw new BaseException("请选择数据!");
        }
        EntityWrapper<PsupFixedPrice> ew = new EntityWrapper<>();
        ew.in("id", idList);
        ew.ne("status", SdCommonEnum.NEW.getCode());
        int count = this.selectCount(ew);
        if (count > 0) {
            throw new BaseException("存在非新增的数据, 不可删除");
        }
        this.deleteBatchIds(idList);
        return null;
    }

    /**
     * 更新价格
     *
     * @param psupFixedPriceVO
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updateSdFixedPrice(PsupFixedPriceVO psupFixedPriceVO) {
        if (Objects.nonNull(psupFixedPriceVO) && Objects.nonNull(psupFixedPriceVO.getId())) {
            if (Objects.isNull(psupFixedPriceVO.getEffectiveDate())) {
                throw new BaseException("生效日期为空!");
            }
            if (Objects.isNull(psupFixedPriceVO.getInvalidDate())) {
                throw new BaseException("失效日期为空!");
            }
            if (Objects.isNull(psupFixedPriceVO.getFleetId()) || StringUtils.isBlank(psupFixedPriceVO.getFleetName())) {
                throw new BaseException("车队信息为空!");
            }
            if (Objects.isNull(psupFixedPriceVO.getPrice())) {
                throw new BaseException("价格为空");
            }
            PsupFixedPrice insertFixedPrice = new PsupFixedPrice();
            BeanUtils.copyProperties(psupFixedPriceVO, insertFixedPrice);
            cleanBlankCloumn(insertFixedPrice);
            this.updateAllColumnById(insertFixedPrice);
        }
    }

    /**
     * 清空数据
     *
     * @param insertFixedPrice
     */
    private void cleanBlankCloumn(PsupFixedPrice insertFixedPrice) {
        if (StringUtils.isBlank(insertFixedPrice.getStartProvince())) {
            insertFixedPrice.setStartProvince(null);
        }
        if (StringUtils.isBlank(insertFixedPrice.getStartCity())) {
            insertFixedPrice.setStartCity(null);
        }
        if (StringUtils.isBlank(insertFixedPrice.getStartCounty())) {
            insertFixedPrice.setStartCounty(null);
        }
        if (StringUtils.isBlank(insertFixedPrice.getStartName())) {
            insertFixedPrice.setStartName(null);
        }
        if (StringUtils.isBlank(insertFixedPrice.getEndProvince())) {
            insertFixedPrice.setEndProvince(null);
        }
        if (StringUtils.isBlank(insertFixedPrice.getEndCity())) {
            insertFixedPrice.setEndCity(null);
        }
        if (StringUtils.isBlank(insertFixedPrice.getEndCounty())) {
            insertFixedPrice.setEndCounty(null);
        }
        if (StringUtils.isBlank(insertFixedPrice.getEndName())) {
            insertFixedPrice.setEndName(null);
        }
        if (StringUtils.isBlank(insertFixedPrice.getContractVehicle())) {
            insertFixedPrice.setContractVehicle(null);
        }
    }

    /**
     * 校验数据并获取车队id
     *
     * @param voList
     * @param token
     * @return
     */
    private List<String> verifyInsertParam(List<PsupFixedPriceVO> voList, String token) {
        Map<String, Long> fleetMap = getFleetMap(voList, token);
        if (Objects.nonNull(fleetMap)) {
            voList.stream()
                    .filter(fixedPriceVO -> StringUtils.isNotBlank(fixedPriceVO.getFleetName()))
                    .forEach(fixedPriceVO -> {
                        Long fleetId = fleetMap.get(fixedPriceVO.getFleetName());
                        if (Objects.nonNull(fleetId)) {
                            fixedPriceVO.setFleetId(fleetId);
                        }
                    });
        }
        List<String> resultMsgList = Lists.newArrayList();
        for (int i = 0, n = voList.size(); i < n; i++) {
            PsupFixedPriceVO fixedPriceVO = voList.get(i);
            StringBuilder sb = new StringBuilder();
            if (StringUtils.isBlank(sb) && Objects.isNull(fixedPriceVO.getEffectiveDate())) {
                sb.append("生效日期为空!");
            }
            if (StringUtils.isBlank(sb) && Objects.isNull(fixedPriceVO.getInvalidDate())) {
                sb.append("失效日期为空!");
            }
            if (StringUtils.isBlank(sb) && Objects.isNull(fixedPriceVO.getPrice())) {
                sb.append("价格为空!");
            }
            // if (StringUtils.isBlank(sb) && StringUtils.isBlank(fixedPriceVO.getContractVehicle())) {
            //     sb.append("合同车型名称为空!");
            // }
            if (StringUtils.isBlank(sb) && StringUtils.isBlank(fixedPriceVO.getFleetName())) {
                sb.append("车队名称为空!");
            }
            if (StringUtils.isBlank(sb) && StringUtils.isBlank(fixedPriceVO.getStartProvince())) {
                sb.append("起运省为空!");
            }
            if (StringUtils.isBlank(sb) && StringUtils.isBlank(fixedPriceVO.getStartCity())) {
                sb.append("起运市为空!");
            }
            if (StringUtils.isBlank(sb) && StringUtils.isBlank(fixedPriceVO.getEndProvince())) {
                sb.append("目的省为空!");
            }
            if (StringUtils.isBlank(sb) && StringUtils.isBlank(fixedPriceVO.getEndCity())) {
                sb.append("目的市为空!");
            }
            if (StringUtils.isNotBlank(sb)) {
                sb.insert(0, "行数:第" + (i + 1) + "行:");
                resultMsgList.add(sb.toString());
            }
        }
        return resultMsgList;
    }

    /**
     * 查询车队信息
     *
     * @param fixedPriceVOList
     * @param token
     * @return
     */
    private Map<String, Long> getFleetMap(List<PsupFixedPriceVO> fixedPriceVOList, String token) {
        List<LspFleetDTO> dtoList = Lists.newArrayList();
        fixedPriceVOList.stream()
                .filter(traditionPrice -> StringUtils.isNotBlank(traditionPrice.getFleetName()))
                .forEach(traditionPrice -> {
                    LspFleetDTO lspFleetDTO = new LspFleetDTO();
                    lspFleetDTO.setFleetName(traditionPrice.getFleetName());
                    dtoList.add(lspFleetDTO);
                });
        List<LspFleetDTO> fleetList = lspUtil.getFleetAll(dtoList, token);
        if (CollectionUtils.isNotEmpty(fleetList)) {
            Map<String, Long> fleetMap = Maps.newHashMap();
            fleetList.forEach(fleet -> {
                fleetMap.put(fleet.getFleetName(), fleet.getId());
            });
            return fleetMap;
        }
        return null;
    }

    private EntityWrapper<PsupFixedPrice> buildCondition(Map<String, Object> condition) {
        EntityWrapper<PsupFixedPrice> ew = new EntityWrapper<>();
        ew.orderBy("id desc");
        if (Objects.nonNull(condition)) {
            // 时间
            Object effectiveDateObj = condition.get("effectiveDate");
            if (Objects.nonNull(effectiveDateObj) && StringUtils.isNotBlank(effectiveDateObj.toString())) {
                Date effectiveDate = ToolCommonUtils.getDateByStr(effectiveDateObj.toString(), ToolCommonUtils.yyyyMMdd);
                ew.le("effective_date", effectiveDate);
                ew.ge("invalid_date", effectiveDate);
            }
            // 车队
            startAndEndInfo(condition, ew, "fleetId", "fleet_id", false);
            // 车队名称
            startAndEndInfo(condition, ew, "fleetName", "fleet_name", true);
            // 状态
            startAndEndInfo(condition, ew, "status", "status", false);
            // 起运省
            startAndEndInfo(condition, ew, "startProvince", "start_province", true);
            // 起运市
            startAndEndInfo(condition, ew, "startCity", "start_city", true);
            // 起运区
            startAndEndInfo(condition, ew, "startCounty", "start_county", true);
            // 起运名称
            startAndEndInfo(condition, ew, "startName", "start_name", true);
            // 目的省
            startAndEndInfo(condition, ew, "endProvince", "end_province", true);
            // 目的市
            startAndEndInfo(condition, ew, "endCity", "end_city", true);
            // 目的区
            startAndEndInfo(condition, ew, "endCounty", "end_county", true);
            // 目的名称
            startAndEndInfo(condition, ew, "endName", "end_name", true);
        }
        return ew;
    }

    private void startAndEndInfo(Map<String, Object> condition, EntityWrapper ew, String key, String column, boolean isLike) {
        // 车队名称
        Object value = condition.get(key);
        if (Objects.nonNull(value) && StringUtils.isNotBlank(value.toString())) {
            if (isLike) {
                ew.like(column, value.toString());
            } else {
                ew.eq(column, value.toString());
            }

        }
    }
}
